package com.mocchira.music.radio;


import java.io.File;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Queue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.json.JSONArray;
import org.json.JSONObject;

import com.google.ads.AdRequest;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

public class FMRPlayActivity extends Activity implements IDownloadListener {
    ImageView imagePlay;
    TextView textArtist;
    TextView textAlbum;
    TextView textTrack;
    TextView textLastfmUrl;
    TextView textBloggedUrl;
    Button buttonBuyAlbum;
    Button buttonBuyMP3;
    Button buttonShare;
    ImageButton buttonPrev;
    ImageButton buttonPlayOrPause;
    ImageButton buttonForward;
    ImageButton buttonFavorite;
    SeekBar seekBar;
    
    MediaPlayerWrapper player;
    DownloadManager manager = new DownloadManager(this, this);
    boolean isInitialized = false;
    
    FavoriteLists favList;
    
    private TelephonyManager mTelephonyManager;
    private boolean previousPlayState = false;
    
    SharePopupWindow popup = null;

    static final String TWEET_PREFIX = " via http://goo.gl/PmSJm";
    static final String TWITTER_PREFIX = "http://twitter.com/?status=";
    
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        player.finalize();
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (favList != null) favList.finalize();
    }

    @Override
    protected void onResume() {
        super.onResume();
        favList = new FavoriteLists(this);
        if (favList != null) {
            buttonFavorite.setEnabled(!favList.isExist(player.getNowPlaying()));
            if (!favList.addable())
                buttonFavorite.setEnabled(false);
        }
    }
    
    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String number) {
            switch(state) {
            case TelephonyManager.CALL_STATE_RINGING:
                /* 着信 */
                try {
                    previousPlayState = player.isPlaying();
                } catch (Exception ex) {
                    previousPlayState = false;
                }
                pause();
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                /* 通話 */
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                /* 待ち受け */
                if (previousPlayState)
                    play();
                break;
            };
        }
    };
    
    protected MediaPlayerWrapper initPlayer(Bundle artistInfo) {
        String tag = (String)artistInfo.get(R.string.bundle_tag + "");
        String artist = (String)artistInfo.get(R.string.bundle_artist + "");
        String latestTag = (String)artistInfo.get(R.string.bundle_latest_tag + "");
        return new MediaPlayerWrapper(tag, artist, latestTag);
    }
    
    protected boolean isSameRequest(Bundle artistInfo) {
        String tag = (String)artistInfo.get(R.string.bundle_tag + "");
        String artist = (String)artistInfo.get(R.string.bundle_artist + "");
        String latestTag = (String)artistInfo.get(R.string.bundle_latest_tag + "");
        return player.isSameRequest(tag, artist, latestTag);
    }
    
    @Override
    protected void onNewIntent(Intent intent) {
        if (player != null) {
            if (isSameRequest(intent.getExtras())) {
                return;
            } else {
                player.finalize();
                isInitialized = false;
            }
        }
        player = initPlayer(intent.getExtras());
        disable();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        
        setContentView(R.layout.play);

        player = initPlayer(getIntent().getExtras());
        
        imagePlay = (ImageView)findViewById(R.id.image_play);
        imagePlay.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                buyMusic();
            }
        });
        textArtist = (TextView)findViewById(R.id.text_artist);
        textArtist.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buyMusic();
            }
        });
        textAlbum = (TextView)findViewById(R.id.text_album);
        textAlbum.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buyMusic();
            }
        });
        textTrack = (TextView)findViewById(R.id.text_track);
        textTrack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buyMP3();
            }
        });
        textLastfmUrl = (TextView)findViewById(R.id.text_lastfm_url);
        textLastfmUrl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = textLastfmUrl.getText().toString();
                Uri uri = Uri.parse(url);
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(intent);
            }
        });
        textBloggedUrl = (TextView)findViewById(R.id.text_blogged_url);
        textBloggedUrl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = textBloggedUrl.getText().toString();
                Uri uri = Uri.parse(url);
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(intent);
            }
        });
        buttonBuyAlbum = (Button)findViewById(R.id.button_buy_album);
        buttonBuyAlbum.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                buyMusic();
            }
        });
        buttonBuyMP3 = (Button)findViewById(R.id.button_buy_mp3);
        buttonBuyMP3.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                buyMP3();
            }
        });
        buttonPrev = (ImageButton)findViewById(R.id.button_prev);
        buttonPrev.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                JSONObject track = player.prev();
                display(track);
            }
        });
        buttonPlayOrPause = (ImageButton)findViewById(R.id.button_play_or_pause);
        buttonPlayOrPause.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                onTogglePlayOrPause();
            }
        });
        buttonForward = (ImageButton)findViewById(R.id.button_forward);
        buttonForward.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                JSONObject track = player.next();
                display(track);
            }
        });
        buttonFavorite = (ImageButton)findViewById(R.id.button_favorite);
        buttonFavorite.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                try {
                    favList.add(player.getNowPlaying());
                } catch (Exception ex) {};
                buttonFavorite.setEnabled(false);
            }
        });
        buttonShare = (Button)findViewById(R.id.button_share);
        buttonShare.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                String tweet = "#nowplaying " + textTrack.getText().toString() + " by " + textArtist.getText().toString() + TWEET_PREFIX;
                popup = SharePopupWindow.getInstance(FMRPlayActivity.this, tweet);
                popup.show(FMRPlayActivity.this.getWindow().getDecorView());
            }
        });
        seekBar = (SeekBar)findViewById(R.id.seekBar);
        seekBar.setMax(100);
        seekBar.setEnabled(false);
        disable();

        //AdRequest request = new AdRequest();
        //request.addTestDevice(AdRequest.TEST_EMULATOR);
    }
    
    protected void buyMP3() {
        String artist = textArtist.getText().toString();
        String track = textTrack.getText().toString();
        String url = AmazonAssociateUtil.getMP3LinkURL(Locale.getDefault(), artist, track);
        Uri uri = Uri.parse(url);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }
    
    protected void buyMusic() {
        String artist = textArtist.getText().toString();
        String album = textAlbum.getText().toString();
        String url = AmazonAssociateUtil.getMusicLinkURL(Locale.getDefault(), artist, album);
        Uri uri = Uri.parse(url);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }
    
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            if (popup != null && popup.isShowing()) {
                popup.dismiss();
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }else{
            return false;
        }
    }
    
    public void play() {
        buttonPlayOrPause.setImageResource(R.drawable.pause);
        player.start();
    }
    
    public void pause() {
        buttonPlayOrPause.setImageResource(R.drawable.play);
        player.pause();
    }
    
    public void onTogglePlayOrPause() {
        if (player.isPlaying()) {
            pause();
        } else {
            play();
        }
    }
    
    @Override
    public void onComplete(String url, File tmpFile, Exception ex) {
        if (ex != null) return;
        Bitmap bm = BitmapFactory.decodeFile(tmpFile.getAbsolutePath());
        imagePlay.setImageBitmap(bm);
        tmpFile.delete();
    }
    
    protected void display(JSONObject track) {
        if (track == null) return;
        enable();
        try {
            /*
            String imgUrl = track.getString("album_img_url");
            if (imgUrl == null || imgUrl.length() == 0) {
                imgUrl = track.getString("artist_img_url");
            }
            if (imgUrl != null && imgUrl.length() > 0) {
                manager.enqueue(imgUrl);
            }
            */
            imagePlay.setImageResource(R.drawable.loading);
            textArtist.setText(track.getString("artist_name"));
            textAlbum.setText(track.getString("album_name"));
            textTrack.setText(track.getString("track_name"));
            textLastfmUrl.setText(track.getString("track_lastfm_url"));
            textBloggedUrl.setText(track.getString("logged_url"));
            buttonFavorite.setEnabled(!favList.isExist(track));
            if (!favList.addable())
                buttonFavorite.setEnabled(false);
        } catch (Exception ex) {
            Log.e(this.getClass().getName(), ex.getMessage(), ex);
        }
    }
    
    protected void displayImage(JSONObject track) {
        if (track == null) return;
        try {
            String imgUrl = track.getString("album_img_url");
            if (imgUrl == null || imgUrl.length() == 0) {
                imgUrl = track.getString("artist_img_url");
            }
            if (imgUrl != null && imgUrl.length() > 0) {
                manager.enqueue(imgUrl);
            }
        } catch (Exception ex) {
            Log.e(this.getClass().getName(), ex.getMessage(), ex);
        }
    }
    
    protected void disable() {
        buttonPrev.setEnabled(false);
        buttonPlayOrPause.setEnabled(false);
        buttonForward.setEnabled(false);
        buttonBuyAlbum.setEnabled(false);
        buttonBuyMP3.setEnabled(false);
        buttonFavorite.setEnabled(false);
        buttonShare.setEnabled(false);
    }
    
    protected void enable() {
        if (player.hasPrev()) {
            buttonPrev.setEnabled(true);
        } else {
            buttonPrev.setEnabled(false);
        }
        buttonPlayOrPause.setEnabled(true);
        buttonBuyAlbum.setEnabled(true);
        buttonBuyMP3.setEnabled(true);
        buttonForward.setEnabled(true);
        buttonFavorite.setEnabled(true);
        buttonShare.setEnabled(true);
    }

    class MediaPlayerWrapper implements MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnBufferingUpdateListener {
        private BasePlayListController playlistController;
        private ArrayList<JSONObject> playedList = new ArrayList<JSONObject>();
        private int idx = 0; 
        private MediaPlayer player = new MediaPlayer();
        private JSONObject nowPlaying;
        
        private boolean isInitialized = false;
        
        private ProgressDialog progress = null;
        
        private int errCounter = 0;
        
        private static final int MAX_CONTINUOUS_ERROR_NUM = 5;

        public MediaPlayerWrapper(String tag, String artist, String latestTag) {
            super();
            if (tag != null)
                playlistController = new PlayListController(tag);
            else if (artist != null)
                playlistController = new ArtistPlayListController(artist);
            else
                playlistController = new LatestTagPlayListController(latestTag);
            player.setOnCompletionListener(this);
            player.setOnErrorListener(this);
            player.setOnPreparedListener(this);
            player.setOnBufferingUpdateListener(this);
            player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
        
        public boolean isSameRequest(String tag, String artist, String latestTag) {
            if (tag != null) {
                return tag.equals(playlistController.getSpecifiedKey());
            } else if (artist != null) {
                return artist.equals(playlistController.getSpecifiedKey());
            } else {
                return latestTag.equals(playlistController.getSpecifiedKey());
            }
        }
        
        public void finalize() {
            player.release();
            playlistController.destroy();
            if (playedList != null)
                playedList.clear();
            playedList = null;
            System.gc();
        }
        
        private void prepareDownload(String flashHtml) {
            Pattern pattern = Pattern.compile("audio_file=([^&]+?)&");
            Matcher matcher = pattern.matcher(flashHtml);
            if (matcher.find()) {
                String url = matcher.group(1);
                url += "?plead=please-dont-download-this-or-our-lawyers-wont-let-us-host-audio";
                try {
                    if (progress != null && progress.isShowing())
                        progress.dismiss();
                    this.progress = ProgressDialog.show(FMRPlayActivity.this, "preparing...", "Download MP3 File");
                    prepare(url);
                } catch (Exception ex) {
                    if (progress.isShowing())
                        try {progress.dismiss();}catch (Exception nex){};
                    Log.e(this.getClass().getName(), ex.getMessage(), ex);
                }
            }
        }
        private void prepare(String track) throws Exception {
            isInitialized = false;
            player.reset();
            player.setDataSource(track);
            player.prepareAsync();
            seekBar.setProgress(0);
        }
        @Override
        public void onBufferingUpdate(MediaPlayer mp, int percent) {
            seekBar.setProgress(percent);
        }
        @Override
        public void onPrepared(MediaPlayer mp) {
            errCounter = 0;
            isInitialized = true;
            if (progress.isShowing())
                try {progress.dismiss();}catch (Exception nex){};
            displayImage(nowPlaying);
            mp.start();
            buttonPlayOrPause.setImageResource(R.drawable.pause);
        }
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            if (progress != null && progress.isShowing())
                try {progress.dismiss();}catch (Exception nex){};
            errCounter++;
            if (errCounter > MAX_CONTINUOUS_ERROR_NUM) {
                errCounter = 0;
                Toast.makeText(FMRPlayActivity.this, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                return true;
            }
            nowPlaying = next();
            display(nowPlaying);
            return false;
        }
        @Override
        public void onCompletion(MediaPlayer mp) {
            nowPlaying = next();
            display(nowPlaying);
        } 
        public void addTrack(JSONObject track) {
            playedList.add(track);
        }
        public JSONObject start() {
            if (isInitialized) {
                player.start();
                return null;
            }
            nowPlaying = playedList.get(idx);
            if (nowPlaying == null) return null;
            try {
                String html = nowPlaying.getString("player_html");
                prepareDownload(html);
            } catch (Exception ex) {
                Log.e(this.getClass().getName(), ex.getMessage(), ex);
            }
            return nowPlaying;
        }
        public void pause() {
            player.pause();
        }
        public JSONObject prev() {
            if (hasPrev()) {
                JSONObject nowPlaying = playedList.get(--idx);
                if (nowPlaying == null) return null;
                try {
                    prepareDownload(nowPlaying.getString("player_html"));
                } catch (Exception ex) {
                    Log.e(this.getClass().getName(), ex.getMessage(), ex);
                }
                return nowPlaying;
            }
            return null;
        }
        public JSONObject next() {
            if (hasNext()) {
                nowPlaying = playedList.get(++idx);
                if (nowPlaying == null) return null;
                try {
                    prepareDownload(nowPlaying.getString("player_html"));
                } catch (Exception ex) {
                    Log.e(this.getClass().getName(), ex.getMessage(), ex);
                }
                return nowPlaying;
            } else {
                nowPlaying = playlistController.getNextTrack();
                if (nowPlaying == null) return null;
                try {
                    idx++;
                    playedList.add(nowPlaying);
                    prepareDownload(nowPlaying.getString("player_html"));
                } catch (Exception ex) {
                    Log.e(this.getClass().getName(), ex.getMessage(), ex);
                }
                return nowPlaying;
            }
        }
        public boolean isPlaying() {
            return player.isPlaying();
        }
        public boolean hasPrev() {
            if (playedList.size() == 0 || idx == 0) {
                return false;
            } else {
                return true;
            }
        }
        public boolean hasNext() {
            if (playedList.size() == 0 || (playedList.size() - 1) ==  idx) {
                return false;
            } else {
                return true;
            }
        }
        public JSONObject getNowPlaying() {
            return nowPlaying;
        }

    }
    
    abstract class BasePlayListController {
        abstract public JSONObject getNextTrack();
        abstract public void destroy();
        abstract public String getSpecifiedKey();
    }
    
    class ArtistPlayListController extends BasePlayListController implements IDownloadListener {
        private DownloadManager manager = new DownloadManager(FMRPlayActivity.this, this);
        private JSONArray playList = null;
        private int currentPos = 0;
        
        private ProgressDialog progress = null;
        private String artist;
        
        private static final String URL_PREFIX = "http://shopping.mocchira.com/hots/";
        
        public ArtistPlayListController(String artist) {
            this.artist = artist;
            String encArtist = "";
            try {
                encArtist = URLEncoder.encode(artist, "UTF-8");
                encArtist = URLEncoder.encode(encArtist, "UTF-8");
            } catch (Exception ex){};
            String url = URL_PREFIX + encArtist;
            manager.enqueue(url);
            this.progress = ProgressDialog.show(FMRPlayActivity.this, "preparing...", "Download Music List File");
        }
        
        @Override
        public void onComplete(String url, File tmpFile, Exception exception) {
            if (this.progress.isShowing())
                try {progress.dismiss();}catch (Exception nex){};
            if (exception != null) {
                Toast.makeText(FMRPlayActivity.this, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                return;
            }
            try {
                String ret = FileUtil.getContents(tmpFile);
                tmpFile.delete();
                JSONObject json = new JSONObject(ret);
                playList = json.getJSONArray("tracks");
            } catch (Exception ex) {
                Log.e(this.getClass().getName(), ex.getMessage(), ex);
                Toast.makeText(FMRPlayActivity.this, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                return;
            }
            JSONObject track = getNextTrack();
            if (track != null) {
                FMRPlayActivity.this.player.addTrack(track);
                if (!FMRPlayActivity.this.isInitialized) {
                    FMRPlayActivity.this.enable();
                    FMRPlayActivity.this.display(track);
                    FMRPlayActivity.this.onTogglePlayOrPause();
                    FMRPlayActivity.this.isInitialized = true;
                }
            }
        }

        @Override
        public JSONObject getNextTrack() {
            if (playList == null || playList.length() == 0) return null;
            JSONObject obj = null;
            try {
                obj = playList.getJSONObject(currentPos);
                if (++currentPos == playList.length())
                    currentPos = 0;
            } catch (Exception ex) {return null;};
            return obj;
        }

        @Override
        public void destroy() {
            playList = null;
            if (progress.isShowing())
                try {progress.dismiss();}catch (Exception nex){};
        }

        @Override
        public String getSpecifiedKey() {
            return artist;
        }
        
    }
    
    class LatestTagPlayListController extends BasePlayListController implements IDownloadListener {
        private DownloadManager manager = new DownloadManager(FMRPlayActivity.this, this);
        private JSONArray playList = null;
        private int currentPos = 0;
        
        private ProgressDialog progress = null;
        private String tag;
        
        private static final String URL_PREFIX = "http://shopping.mocchira.com/latest/";
        
        public LatestTagPlayListController(String tag) {
            this.tag = tag;
            String encTag = "";
            try {
                encTag = URLEncoder.encode(tag, "UTF-8");
                encTag = URLEncoder.encode(encTag, "UTF-8");
            } catch (Exception ex){};
            String url = URL_PREFIX + encTag + ".json";
            manager.enqueue(url);
            this.progress = ProgressDialog.show(FMRPlayActivity.this, "preparing...", "Download Music List File");
        }
        
        @Override
        public void onComplete(String url, File tmpFile, Exception exception) {
            if (this.progress.isShowing())
                try {progress.dismiss();}catch (Exception nex){};
            if (exception != null) {
                Toast.makeText(FMRPlayActivity.this, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                return;
            }
            try {
                String ret = FileUtil.getContents(tmpFile);
                tmpFile.delete();
                JSONObject json = new JSONObject(ret);
                playList = json.getJSONArray("tracks");
            } catch (Exception ex) {
                Log.e(this.getClass().getName(), ex.getMessage(), ex);
                Toast.makeText(FMRPlayActivity.this, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                return;
            }
            JSONObject track = getNextTrack();
            if (track != null) {
                FMRPlayActivity.this.player.addTrack(track);
                if (!FMRPlayActivity.this.isInitialized) {
                    FMRPlayActivity.this.enable();
                    FMRPlayActivity.this.display(track);
                    FMRPlayActivity.this.onTogglePlayOrPause();
                    FMRPlayActivity.this.isInitialized = true;
                }
            }
        }

        @Override
        public JSONObject getNextTrack() {
            if (playList == null || playList.length() == 0) return null;
            JSONObject obj = null;
            try {
                obj = playList.getJSONObject(currentPos);
                if (++currentPos == playList.length())
                    currentPos = 0;
            } catch (Exception ex) {return null;};
            return obj;
        }

        @Override
        public void destroy() {
            playList = null;
            if (progress.isShowing())
                try {progress.dismiss();}catch (Exception nex){};
        }

        @Override
        public String getSpecifiedKey() {
            return tag;
        }
        
    }
    
    class PlayListController extends BasePlayListController implements IDownloadListener {
        private String tag;
        private DownloadManager manager = new DownloadManager(FMRPlayActivity.this, this);
        private Queue<JSONArray> playList = new LinkedList<JSONArray>();
        private JSONArray currentBuffer = null;
        private int totalSize = 0;
        private int bufIndex = 0;
        private boolean isProcessed = false;
        
        private int errCount = 0;
        
        private static final int MAX_CONTINUOUS_ERROR_NUM = 5;
        private static final String URL_PREFIX = "http://radio.music.mocchira.com/fmr/music?m=musics&";
        
        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (!PlayListController.this.isProcessed && PlayListController.this.totalSize < 3) {
                    enqueue();
                    PlayListController.this.isProcessed = true;
                }
                handler.sendEmptyMessageDelayed(0, 1000);
            }
        };
        public PlayListController(String tag) {
            this.tag = tag;
            handler.sendEmptyMessage(0);
        }
        public void enqueue() {
            String url = URL_PREFIX + "tag=" + tag + "&start=-1";
            manager.enqueue(url);
        }
        @Override
        public void onComplete(String url, File tmpFile, Exception exception) {
            PlayListController.this.isProcessed = false;
            if (exception != null) {
                errCount++;
                if (errCount > MAX_CONTINUOUS_ERROR_NUM) {
                    errCount = 0;
                    handler.removeMessages(0);
                    Toast.makeText(FMRPlayActivity.this, R.string.msg_network_err, Toast.LENGTH_LONG).show();
                }
                return;
            }
            errCount = 0;
            Log.d(this.getClass().getName(), url + tmpFile.toString());
            String ret = "";
            try {
                ret = FileUtil.getContents(tmpFile);
                tmpFile.delete();
                JSONObject json = new JSONObject(ret);
                JSONArray array = json.getJSONArray("tracks");
                playList.offer(array);
                totalSize += array.length();
            } catch (Exception ex) {
                Log.e(this.getClass().getName(), ex.getMessage(), ex);
                return;
            }
            JSONObject track = getNextTrack();
            if (track != null) {
                FMRPlayActivity.this.player.addTrack(track);
                if (!FMRPlayActivity.this.isInitialized) {
                    FMRPlayActivity.this.enable();
                    FMRPlayActivity.this.display(track);
                    FMRPlayActivity.this.onTogglePlayOrPause();
                    FMRPlayActivity.this.isInitialized = true;
                }
            }
        }
        
        @Override
        public JSONObject getNextTrack() {
            handler.sendEmptyMessageDelayed(0, 1000);
            if (totalSize == 0) return null;
            if (currentBuffer == null || (currentBuffer.length()  == bufIndex)) {
                bufIndex = 0;
                currentBuffer = playList.poll(); 
            }
            if (currentBuffer == null) return null;
            JSONObject ret = null;
            try {
                ret = (JSONObject)currentBuffer.get(bufIndex++);
            } catch (Exception ex) {
                Log.e(this.getClass().getName(), ex.getMessage(), ex);
            }
            totalSize--;
            return ret;
        }
        @Override
        public void destroy() {
            playList = null;
            currentBuffer = null;
            handler.removeMessages(0);
        }
        @Override
        public String getSpecifiedKey() {
            return tag;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, FMRTopActivity.MENU_FAVORITE, 0, R.string.favorite);
        return true;
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch (item.getItemId()) {
        case FMRTopActivity.MENU_FAVORITE:
            buttonPlayOrPause.setImageResource(R.drawable.play);
            player.pause();
            Intent intent = new Intent(this, FMRFavoriteActivity.class);
            startActivity(intent);
            break;
        }
        return super.onMenuItemSelected(featureId, item);
    }
    
}
